package sso.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;


import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import sso.utill.JwtUtils;
import sso.utill.WebUtils;


import java.util.*;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //1.关闭跨域攻击
        http.csrf().disable();
        //2.配置form认证
        http.formLogin()
                .successHandler(successHandler()) //登录成功
                .failureHandler(failureHandler());//登录失败
        http.exceptionHandling()
                .authenticationEntryPoint(entryPoint());  //提示需要认证
        //3.所有资源都要认证
        http.authorizeRequests().anyRequest().authenticated();
    }

    /*登录成功的处理器*/
    private AuthenticationSuccessHandler successHandler(){
        //匿名内部类的简单写法
        return (request, response, authentication) -> {
            Map<String,Object> map = new HashMap<>();
            map.put("state","200");
            map.put("message","欢迎你,登录成功!");
            Map<String,Object> userInfo = new HashMap<>();
            //获取用户对象，此对象为登录成功以后封装的登录信息的对象
            User user = (User) authentication.getPrincipal();
            //获取用户名
            userInfo.put("username",user.getUsername());
            //获取用户权限并封装到userInfo中
            List<String> authorities = new ArrayList<>();
            user.getAuthorities().forEach((authority)->{
                authorities.add(authority.getAuthority());//sys:res:create
            });
            userInfo.put("authorities", authorities);
            String token = JwtUtils.generateToken(userInfo);
            map.put("token",token);
            WebUtils.writeJsonToClient(response, map);
        };
    }

    /*登录失败的处理器*/
    private AuthenticationFailureHandler failureHandler(){
        return (request,response,exception)->{
            Map<String,Object> map = new HashMap<>();
            map.put("state", "500");
            map.put("message","登录失败(密码或者账号输入错误)！");
            WebUtils.writeJsonToClient(response, map);
        };
    }

    /*未登录访问资源时给出提示*/
    private AuthenticationEntryPoint entryPoint(){
        return (request,response,exception)->{
            Map<String,Object> map = new HashMap<>();
            map.put("state", "401");
            map.put("message","请先登录！");
            WebUtils.writeJsonToClient(response, map);
        };
    }
}
